package com.wd.jetpack.util

import android.content.Context
import android.util.Log
import java.util.*
object Logger {
    /**
     * debug开关.
     */
    var D = true

    /**
     * info开关.
     */
    var I = true

    /**
     * error开关.
     */
    var E = true

    /**
     * 起始执行时间.
     */
    var startLogTimeInMillis: Long = 0
    private const val TAG = "DOUBLE_SCREEN"

    /**
     * debug日志
     *
     * @param tag
     * @param message
     */
    fun d(tag: String?, message: String?) {
        if (D) message?.let { Log.d(tag, it) }
    }

    fun w(tag: String?, message: String?) {
        if (D) message?.let { Log.w(tag, it) }
    }

    fun d(message: String?) {
        if (D) if (message != null && message != "") Log.d(TAG, "${message} ${functionName}")
    }

    /**
     * debug日志
     *
     * @param context
     * @param message
     */
    fun d(context: Context, message: String?) {
        val tag = context.javaClass.simpleName
        d(tag, message)
    }

    /**
     * debug日志
     *
     * @param clazz
     * @param message
     */
    fun d(clazz: Class<*>, message: String?) {
        val tag = clazz.simpleName
        d(tag, message)
    }

    /**
     * info日志
     *
     * @param tag
     * @param message
     */
    fun i(tag: String?, message: String?) {
        message?.let { Log.i(tag, it) }
    }

    fun i(message: String?) {
        if (I) message?.let { Log.i(TAG, it) }
    }

    /**
     * info日志
     *
     * @param context
     * @param message
     */
    fun i(context: Context, message: String?) {
        val tag = context.javaClass.simpleName
        i(tag, message)
    }

    /**
     * info日志
     *
     * @param clazz
     * @param message
     */
    fun i(clazz: Class<*>, message: String?) {
        val tag = clazz.simpleName
        i(tag, message)
    }

    /**
     * error日志
     *
     * @param tag
     * @param message
     */
    fun e(tag: String?, message: String?) {
        if (message != null) {
            Log.e(tag, message)
        }
    }

    fun e(message: String?) {
        if (E) message?.let { Log.e(TAG, it) }
    }

    /**
     * error日志
     *
     * @param context
     * @param message
     */
    fun e(context: Context, message: String?) {
        val tag = context.javaClass.simpleName
        e(tag, message)
    }

    /**
     * error日志
     *
     * @param clazz
     * @param message
     */
    fun e(clazz: Class<*>, message: String?) {
        val tag = clazz.simpleName
        e(tag, message)
    }

    /**
     * 描述：记录当前时间毫秒.
     */
    fun prepareLog(tag: String?) {
        val current = Calendar.getInstance()
        startLogTimeInMillis = current.timeInMillis
        Log.d(tag, "日志计时开始：$startLogTimeInMillis")
    }

    /**
     * 描述：记录当前时间毫秒.
     */
    fun prepareLog(context: Context) {
        val tag = context.javaClass.simpleName
        prepareLog(tag)
    }

    /**
     * 描述：记录当前时间毫秒.
     */
    fun prepareLog(clazz: Class<*>) {
        val tag = clazz.simpleName
        prepareLog(tag)
    }

    /**
     * 描述：打印这次的执行时间毫秒，需要首先调用prepareLog().
     *
     * @param tag       标记
     * @param message   描述
     * @param printTime 是否打印时间
     */
    fun d(tag: String?, message: String, printTime: Boolean) {
        val current = Calendar.getInstance()
        val endLogTimeInMillis = current.timeInMillis
        Log.d(tag, message + ":" + (endLogTimeInMillis - startLogTimeInMillis)
                + "ms")
    }

    /**
     * 描述：打印这次的执行时间毫秒，需要首先调用prepareLog().
     *
     * @param context   标记
     * @param message   描述
     * @param printTime 是否打印时间
     */
    fun d(context: Context, message: String, printTime: Boolean) {
        val tag = context.javaClass.simpleName
        d(tag, message, printTime)
    }

    /**
     * 描述：打印这次的执行时间毫秒，需要首先调用prepareLog().
     *
     * @param clazz     标记
     * @param message   描述
     * @param printTime 是否打印时间
     */
    fun d(clazz: Class<*>, message: String, printTime: Boolean) {
        val tag = clazz.simpleName
        d(tag, message, printTime)
    }

    /**
     * debug日志的开关
     *
     * @param d
     */
    fun debug(d: Boolean) {
        D = d
    }

    /**
     * info日志的开关
     *
     * @param i
     */
    fun info(i: Boolean) {
        I = i
    }

    /**
     * error日志的开关
     *
     * @param e
     */
    fun error(e: Boolean) {
        E = e
    }

    /**
     * 设置日志的开关
     *
     * @param e
     */
    fun setVerbose(d: Boolean, i: Boolean, e: Boolean) {
        D = d
        I = i
        E = e
    }

    /**
     * 打开所有日志，默认全打开
     */
    fun openAll() {
        D = true
        I = true
        E = true
    }

    /**
     * 关闭所有日志
     */
    fun closeAll() {
        D = false
        I = false
        E = false
    }

    /**
     * 获取相关数据:类名,方法名,行号等.用来定位行<br></br>
     * at cn.utils.MainActivity.onCreate(MainActivity.java:17) 就是用來定位行的代碼<br></br>
     *
     * @return [ Thread:main, at
     * cn.utils.MainActivity.onCreate(MainActivity.java:17)]
     */
    private val functionName: String?
        private get() {
            val sts = Thread.currentThread().stackTrace
            if (sts != null) {
                for (st in sts) {
                    if (st.isNativeMethod) {
                        continue
                    }
                    if (st.className == Thread::class.java.name) {
                        continue
                    }
                    if (st.className == Logger::class.java.name) {
                        continue
                    }
                    return ("[ Thread:" + Thread.currentThread().name + ", at " + st.className + "." + st.methodName
                            + "(" + st.fileName + ":" + st.lineNumber + ")" + " ]")
                }
            }
            return null
        }
}